package com.tcm.item.service.drugs;

import cn.hutool.core.util.ObjectUtil;
import com.base.core.exception.ServiceException;
import com.base.core.utils.R;
import com.base.genid.generator.UidGenerator;
import com.base.core.pager.PageBean;
import com.base.core.dozer.DozerConvert;
import com.base.core.pager.PageContext;
import com.base.core.utils.ListUtils;
import com.tcm.item.domain.dto.DrugsDTO;
import com.tcm.item.domain.entity.Drugs;
import com.tcm.item.domain.entity.DrugsCategory;
import com.tcm.item.domain.enums.BusinessCodeEnum;
import com.tcm.item.mapper.DrugsCategoryMapper;
import com.tcm.item.mapper.DrugsMapper;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;


@DubboService(version = "0.0.1-alpha", retries = 3, timeout = 3000)
public class DrugsServiceImpl implements  DrugsService{

    @Autowired
    private DrugsMapper drugsMapper;

    @Autowired
    private DrugsCategoryMapper drugsCategoryMapper;


    @DubboReference(version = "0.0.1-beta", group = "cached-uid", retries = 3, timeout = 3000,check = false)
    private UidGenerator uidGenerator;

    @Transactional
    @Override
    public void save(DrugsDTO drugsDto) throws ServiceException {
        if(ObjectUtil.isEmpty(drugsDto.getCategoryId())){
            R.throwFail(BusinessCodeEnum.PRODUCT_CATEGORY_NOT_EXISTS);
        }
        //检查是否叶子类
        List<DrugsCategory> drugsCategoryList = drugsCategoryMapper.findChildList(drugsDto.getCategoryId());
        if(ListUtils.isNotEmpty(drugsCategoryList)){
            R.throwFail(BusinessCodeEnum.PRODUCT_SPU_CATEGORY_MUST_BE_LEAF);
        }
        if(ObjectUtil.isEmpty(drugsDto.getStoreId())){
            R.throwFail(BusinessCodeEnum.PRODUCT_SUPPLIER_NOT_EXISTS);
        }
        //同一供应商相同规格商品不能重复添加
        List<Long> drugsIds = drugsMapper.checkDrugsByStoreId(drugsDto.getStoreId(),drugsDto.getName(),
                drugsDto.getSpecs(),null);
        if(ListUtils.isNotEmpty(drugsIds)){
            R.throwFail(BusinessCodeEnum.PRODUCT_SKU_ATTR_CANT_NOT_DUPLICATE);
        }
        if(ObjectUtil.isEmpty(drugsDto.getQuantity())){
            R.throwFail(BusinessCodeEnum.PRODUCT_QUANTITY_NOT_EMPTY);
        }
        Drugs drugs = DozerConvert.copyProperties(drugsDto, Drugs.class);
        drugs.setId(uidGenerator.getUID());
        drugs.setCreateTime(LocalDateTime.now());
        drugs.setUpdateTime(LocalDateTime.now());
        drugs.setStatus(new Byte("1"));
        drugs.setDeleted(new Byte("1"));
        try{
            drugsMapper.insert(drugs);
        }catch (Exception e){
            R.throwFail(e.getMessage());
        }


    }

    @Override
    public void update(DrugsDTO drugsDto) {
        if(ObjectUtil.isEmpty(drugsDto.getId())){
            R.throwFail(BusinessCodeEnum.PRODUCT_ID_NOT_EXISTS);
        }
        if(ObjectUtil.isEmpty(drugsDto.getCategoryId())){
            R.throwFail(BusinessCodeEnum.PRODUCT_CATEGORY_NOT_EXISTS);
        }
        //检查是否叶子类
        List<DrugsCategory> drugsCategoryList = drugsCategoryMapper.findChildList(drugsDto.getCategoryId());
        if(ListUtils.isNotEmpty(drugsCategoryList)){
            R.throwFail(BusinessCodeEnum.PRODUCT_SPU_CATEGORY_MUST_BE_LEAF);
        }
        if(ObjectUtil.isEmpty(drugsDto.getStoreId())){
            R.throwFail(BusinessCodeEnum.PRODUCT_SUPPLIER_NOT_EXISTS);
        }
        //同一供应商相同规格商品不能重复添加
        List<Long> drugsIds = drugsMapper.checkDrugsByStoreId(drugsDto.getStoreId(),drugsDto.getName(),
                drugsDto.getSpecs(),null);
        if(ListUtils.isNotEmpty(drugsIds)){
            R.throwFail(BusinessCodeEnum.PRODUCT_SKU_ATTR_CANT_NOT_DUPLICATE);
        }
        Drugs drugs = DozerConvert.copyProperties(drugsDto, Drugs.class);
        drugs.setUpdateTime(LocalDateTime.now());
        try{
            drugsMapper.update(drugs);
        }catch (Exception e){
            R.throwFail(e.getMessage());
        }
    }

    /**
     * 查询药材数据
     * @param id
     * @return
     */
    @Override
    public DrugsDTO findDrugsById(Long id) {
       Drugs drugs = drugsMapper.findDrugsById(id);
       if(ObjectUtil.isEmpty(drugs)){
           return null;
       }
       DrugsDTO drugsVo = DozerConvert.copyProperties(drugs, DrugsDTO.class);
       return drugsVo;
    }

    /**
     * 通过药房id分页查询药材
     * @param storeId
     * @param start
     * @param pagesize
     * @return
     */
    @Override
    public PageBean<DrugsDTO> listDrugsPageByStoreId(Long storeId, Long start, Long pagesize) {
        Long count = drugsMapper.countDrugsByStoreId(storeId);
        PageContext.setCurrentPage(start);
        PageContext.setPageSize(pagesize);
        PageContext.setDataCount(count);
        if(count.intValue() == 0){
            return new PageBean<>(null);
        }

        List<Drugs> drugsList = drugsMapper.findDrugsPageByStoreId(storeId, PageContext.getStart(),pagesize);
        List<DrugsDTO> drugsDTOS = DozerConvert.copyList(drugsList, DrugsDTO.class);
        PageContext.clear();
        return new PageBean<>(drugsDTOS);
    }

    /**
     * 统计已选择商品价格总和
     *
     * @param drugsIds 已选择的商品id
     * @return
     */
    @Override
    public BigDecimal totalSelectedDrugsPrice(Long[] drugsIds) {
        List<BigDecimal> priceList = drugsMapper.listDrugsPriceByIds(drugsIds);
        BigDecimal totalPrice = new BigDecimal("0.0000");
        for (BigDecimal price : priceList){
            totalPrice.add(price);
        }
        return totalPrice;
    }

    @Override
    public int deleteLogicById(Long id) {
        return drugsMapper.deleteLogicById(id);
    }

    @Override
    public int deleteById(Long id) {
        return drugsMapper.deleteById(id);
    }
}
